/*-----------------------------------------------------------------------------
 * Name:    LED_MCBSTM32F200.c
 * Purpose: LED interface for IMT407G board
 * Rev.:    1.0.0
 *----------------------------------------------------------------------------*/

#include "hal.h"
#include "Board_LED.h"

/* GPIO Pin identifier */
typedef struct _GPIO_PIN
{
    GPIO_TypeDef* port;
    uint16_t      pin;
    uint16_t      reserved;
} GPIO_PIN_t;

// #define LED1_PIN                         GPIO_Pin_6
// #define LED1_GPIO_PORT                   GPIOG
// #define LED1_GPIO_CLK                    RCC_AHB1Periph_GPIOG

// #define LED2_PIN                         GPIO_Pin_8
// #define LED2_GPIO_PORT                   GPIOG
// #define LED2_GPIO_CLK                    RCC_AHB1Periph_GPIOG

// #define LED3_PIN                         GPIO_Pin_9
// #define LED3_GPIO_PORT                   GPIOI
// #define LED3_GPIO_CLK                    RCC_AHB1Periph_GPIOI

// #define LED4_PIN                         GPIO_Pin_7
// #define LED4_GPIO_PORT                   GPIOC
// #define LED4_GPIO_CLK                    RCC_AHB1Periph_GPIOC

/* LED GPIO Pins */
static const GPIO_PIN_t LED_PIN[] =
{
    { GPIOG, GPIO_PIN_8,  0U },
    { GPIOG, GPIO_PIN_6,  0U },
    { GPIOC, GPIO_PIN_7,  0U },
    { GPIOI, GPIO_PIN_9, 0U },
    // { GPIOG, GPIO_PIN_6,  0U },
    // { GPIOG, GPIO_PIN_7,  0U },
    // { GPIOG, GPIO_PIN_8,  0U },
    // { GPIOH, GPIO_PIN_2,  0U }
};

#define LED_COUNT (sizeof(LED_PIN)/sizeof(GPIO_PIN_t))


/**
  \fn          int32_t LED_Initialize (void)
  \brief       Initialize LEDs
  \returns
   - \b  0: function succeeded
   - \b -1: function failed
*/
int32_t LED_Initialize(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;

    /* GPIO Ports Clock Enable */
    __GPIOG_CLK_ENABLE();
    __GPIOC_CLK_ENABLE();
    __GPIOI_CLK_ENABLE();

    for (int i = 0; i < LED_COUNT; ++i)
    {
        GPIO_InitStruct.Pin   = LED_PIN[i].pin;
        GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;
        GPIO_InitStruct.Pull  = GPIO_PULLDOWN;
        GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
        HAL_GPIO_Init(LED_PIN[i].port, &GPIO_InitStruct);

    }



    return 0;
}

/**
  \fn          int32_t LED_Uninitialize (void)
  \brief       De-initialize LEDs
  \returns
   - \b  0: function succeeded
   - \b -1: function failed
*/
int32_t LED_Uninitialize(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    for (int i = 0; i < LED_COUNT; ++i)
    {
        GPIO_InitStruct.Pin   = LED_PIN[i].pin;
        GPIO_InitStruct.Mode  = GPIO_MODE_OUTPUT_PP;
        GPIO_InitStruct.Pull  = GPIO_PULLDOWN;
        GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
        HAL_GPIO_DeInit(LED_PIN[i].port, &GPIO_InitStruct);

    }


    return 0;
}

/**
  \fn          int32_t LED_On (uint32_t num)
  \brief       Turn on requested LED
  \param[in]   num  LED number
  \returns
   - \b  0: function succeeded
   - \b -1: function failed
*/
int32_t LED_Off(uint32_t num)
{
    int32_t retCode = 0;

    if (num < LED_COUNT)
    {
        HAL_GPIO_WritePin(LED_PIN[num].port, LED_PIN[num].pin, GPIO_PIN_SET);
    }
    else
    {
        retCode = -1;
    }

    return retCode;
}

/**
  \fn          int32_t LED_Off (uint32_t num)
  \brief       Turn off requested LED
  \param[in]   num  LED number
  \returns
   - \b  0: function succeeded
   - \b -1: function failed
*/
int32_t LED_On(uint32_t num)
{
    int32_t retCode = 0;

    if (num < LED_COUNT)
    {
        HAL_GPIO_WritePin(LED_PIN[num].port, LED_PIN[num].pin, GPIO_PIN_RESET);
    }
    else
    {
        retCode = -1;
    }

    return retCode;
}

/**
  \fn          int32_t LED_Off (uint32_t num)
  \brief       Turn off requested LED
  \param[in]   num  LED number
  \returns
   - \b  0: function succeeded
   - \b -1: function failed
*/
int32_t LED_Toggle(uint32_t num)
{
    int32_t retCode = 0;

    if (num < LED_COUNT)
    {
        HAL_GPIO_TogglePin(LED_PIN[num].port, LED_PIN[num].pin);
    }
    else
    {
        retCode = -1;
    }

    return retCode;
}





/**
  \fn          int32_t LED_SetOut (uint32_t val)
  \brief       Write value to LEDs
  \param[in]   val  value to be displayed on LEDs
  \returns
   - \b  0: function succeeded
   - \b -1: function failed
*/
int32_t LED_SetOut(uint32_t val)
{
    uint32_t n;

    for (n = 0; n < LED_COUNT; n++)
    {
        if (val & (1 << n))
        {
            LED_On(n);
        }
        else
        {
            LED_Off(n);
        }
    }

    return 0;
}

/**
  \fn          uint32_t LED_GetCount (void)
  \brief       Get number of LEDs
  \return      Number of available LEDs
*/
uint32_t LED_GetCount(void)
{

    return LED_COUNT;
}
